package cn.linjianhui.interview.thread;

import java.util.concurrent.Semaphore;

public class ABCPrinter {

    private final Semaphore semaphoreA = new Semaphore(1);
    private final Semaphore semaphoreB = new Semaphore(0);
    private final Semaphore semaphoreC = new Semaphore(0);

    public void printA() {
        Semaphore currentSemaphore = semaphoreA;
//        try {
//            semaphoreA.acquire();
//            System.out.println("print A");
//        } catch (InterruptedException e) {
//            throw new RuntimeException(e);
//        }finally {
//            semaphoreA.release();
//            semaphoreB.release();
//        }
        print("print A", semaphoreA, semaphoreB);
    }

    public void printB() {
//        try {
//            semaphoreB.acquire();
//            System.out.println("print B");
//        } catch (InterruptedException e) {
//            throw new RuntimeException(e);
//        }finally {
//            semaphoreB.release();
//            semaphoreC.release();
//        }

        print("print B", semaphoreB, semaphoreC);
    }

    public void printC() {
//        try {
//            semaphoreC.acquire();
//            System.out.println("print C");
//        } catch (InterruptedException e) {
//            throw new RuntimeException(e);
//        } finally {
//            semaphoreC.release();
//        }
        print("print C", semaphoreC, semaphoreA);
    }

    public void print(String alphabet, Semaphore currentSemaphore, Semaphore nextSemaphore) {
        try {
            currentSemaphore.acquire();
            System.out.println(Thread.currentThread().getName() + " : " + alphabet);
            nextSemaphore.release();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return;
        }
    }

    public static void main(String[] args) {
        ABCPrinter printer = new ABCPrinter();
        Thread threadA = new Thread(printer::printA, "Thread-A");
        Thread threadB = new Thread(printer::printB, "Thread-B");
        Thread threadC = new Thread(printer::printC, "Thread-C");

        threadA.start();
        threadB.start();
        threadC.start();
    }
}
